package com.arpa.oms.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.IterUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.arpa.ntocc.common.common.cache.AreaCache;
import com.arpa.ntocc.common.common.cache.ShipmentCache;
import com.arpa.ntocc.common.common.exception.ServiceException;
import com.arpa.ntocc.common.common.util.CommonUtil;
import com.arpa.ntocc.common.common.util.UserUtil;
import com.arpa.ntocc.common.domain.enums.CustomerCheckStatusEnum;
import com.arpa.oms.domain.dto.OmsCustomerDTO;
import com.arpa.oms.domain.entity.OmsCustomer;
import com.arpa.oms.domain.vo.OmsCustomerVO;
import com.arpa.oms.mapper.OmsCustomerMapper;
import com.arpa.oms.service.IOmsCustomerService;
import com.arpa.wms.cache.CustomerCache;
import com.arpa.wms.common.util.UUIDUtil;
import com.arpa.wms.domain.consts.NumConst;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * <p>
 * 客户 服务实现类
 * </p>
 *
 * @author LEO
 * @since 2020-09-04
 */
@Service
public class OmsCustomerServiceImpl extends ServiceImpl<OmsCustomerMapper, OmsCustomer> implements IOmsCustomerService {

    private final CustomerCache customerCache;

    private final AreaCache areaCache;
    private final ShipmentCache shipmentCache;

    public OmsCustomerServiceImpl(CustomerCache customerCache, AreaCache areaCache, ShipmentCache shipmentCache) {
        this.customerCache = customerCache;
        this.areaCache = areaCache;
        this.shipmentCache = shipmentCache;
    }

    private static final String THE_CUSTOMER_NAME_ALREADY_EXISTS = "客户名称已存在!";
    private static final String THE_CUSTOMER_NUMBER_ALREADY_EXISTS = "客户编号已存在!";

    /**
     * 保存
     *
     * @param entity
     * @return
     */
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public boolean save(OmsCustomer entity) {
        //校验名称和编码是否重复
        OmsCustomerDTO dto = new OmsCustomerDTO();
        dto.setName(entity.getName());
        List<OmsCustomerVO> name = queryByNameOrCode(dto);
        if (null != name && name.size() > 0) {
            throw new ServiceException(THE_CUSTOMER_NAME_ALREADY_EXISTS);
        }
        dto.setName("");
        dto.setCustomerCode(entity.getCustomerCode());
        List<OmsCustomerVO> code = queryByNameOrCode(dto);
        if (null != code && code.size() > 0) {
            throw new ServiceException(THE_CUSTOMER_NUMBER_ALREADY_EXISTS);
        }

        if (StringUtils.isBlank(entity.getCode())) {
            entity.setCode(IdUtil.simpleUUID());
        }
        if (StringUtils.isBlank(entity.getCreatedBy())) {
            entity.setCreatedBy(UserUtil.getCode());
        }
        entity.setCode(UUIDUtil.getUUID32());
        entity.setCreatedBy(UserUtil.getCode());

        //清除旧缓存
        customerCache.flushAllCacheByGroupCode(UserUtil.getBranchCode());
        return super.save(entity);
    }

    /**
     * 根据code更新实体
     *
     * @param entity
     * @return
     */
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public int updateByCode(OmsCustomer entity) {
        if (entity.getStatus().equals(NumConst.NUM_TWO)) {
            entity.setStatus(NumConst.NUM_ZERO);
        }
        OmsCustomerDTO dto = new OmsCustomerDTO();
        dto.setName(entity.getName());
        List<OmsCustomerVO> name = queryByNameOrCode(dto);
        if (null != name && name.size() > NumConst.NUM_ZERO) {
            OmsCustomerVO customerVO = name.get(NumConst.NUM_ZERO);
            if (!customerVO.getCode().equals(entity.getCode())) {
                throw new ServiceException(THE_CUSTOMER_NAME_ALREADY_EXISTS);
            }
        }


        if (StringUtils.isBlank(entity.getModifiedBy())) {
            entity.setModifiedBy(UserUtil.getCode());
        }

        //清除旧缓存
        customerCache.flushAllCacheByGroupCode(UserUtil.getBranchCode());
        return baseMapper.update(entity, new QueryWrapper<OmsCustomer>().lambda().eq(OmsCustomer::getCode, entity.getCode()));
    }

    /**
     * 查询列表
     *
     * @param customerDTO
     * @return
     */
    @Override
    public List<OmsCustomerVO> queryList(OmsCustomerDTO customerDTO) {
        //排序字段名需要驼峰转数据库下划线类型字段名
        if (StringUtils.isNotEmpty(customerDTO.getSortField())) {
            customerDTO.setSortField(CommonUtil.camel2Underline(customerDTO.getSortField()));
        }
        List<OmsCustomerVO> customerVOList = baseMapper.queryList(customerDTO);
        customerVOList.forEach(e -> {
            CustomerCheckStatusEnum enumByCode = CustomerCheckStatusEnum.getEnumByCode(e.getStatus());
            if (null != enumByCode) {
                e.setStatusText(enumByCode.getDesc());
            }
        });


        return customerVOList;
    }

    @Override
    public List<OmsCustomerVO> queryByNameOrCode(OmsCustomerDTO customerDTO) {

        return baseMapper.queryByNameOrCode(customerDTO);
    }

    /**
     * 查询合计,包含总数
     *
     * @param customerDTO
     * @return
     */
    @Override
    public OmsCustomerVO queryListSum(OmsCustomerDTO customerDTO) {
        OmsCustomerVO customerVO = baseMapper.queryListSum(customerDTO);
        return customerVO;
    }

    @Override
    public int batchDelete(List<String> codes, String modifiedBy) {

        //清除旧缓存
        customerCache.flushAllCacheByGroupCode(UserUtil.getBranchCode());
        return baseMapper.batchDelete(codes, modifiedBy);
    }

    @Override
    public List<OmsCustomerVO> findCustomer(String shipmentCode) {
        List<OmsCustomer> customers = list(new LambdaQueryWrapper<OmsCustomer>().eq(OmsCustomer::getShipmentCode, shipmentCode));
        return customers.stream().map(c -> {
            OmsCustomerVO temp = new OmsCustomerVO();
            BeanUtil.copyProperties(c, temp, false);
            return temp;
        }).collect(Collectors.toList());

    }

    /**
     * 添加客户信息
     *
     * @param dto
     */
    @Override
    public boolean save(OmsCustomerDTO dto) {
        OmsCustomer entity = new OmsCustomer();
        BeanUtil.copyProperties(dto, entity);
        List<String> areaList = dto.getAreaList();
        if (IterUtil.isNotEmpty(areaList) && areaList.size() == NumConst.NUM_FOUR) {
            entity.setCountry(areaList.get(NumConst.NUM_ZERO));
            entity.setProvince(areaList.get(NumConst.NUM_ONE));
            entity.setCity(areaList.get(NumConst.NUM_TWO));
            entity.setCounty(areaList.get(NumConst.NUM_THREE));
        }

        int count = baseMapper.selectCount(new QueryWrapper<OmsCustomer>().lambda().eq(OmsCustomer::getCustomerCode, entity.getCustomerCode()));
        if (count > NumConst.NUM_ZERO) {
            throw new ServiceException(THE_CUSTOMER_NUMBER_ALREADY_EXISTS);
        }
        count = baseMapper.selectCount(new QueryWrapper<OmsCustomer>().lambda().eq(OmsCustomer::getName, entity.getName()));
        if (count > NumConst.NUM_ZERO) {
            throw new ServiceException(THE_CUSTOMER_NAME_ALREADY_EXISTS);
        }
        entity.setStatus(NumConst.NUM_ZERO);
        entity.setCode(UUIDUtil.getUUID32());
        entity.setCreatedBy(UserUtil.getCode());
        entity.setShipmentName(shipmentCache.translate(entity.getShipmentCode()));
        entity.setCreatedName(UserUtil.getPartyCache() != null ? UserUtil.getPartyCache().getName() : "");
        entity.setModifiedBy(UserUtil.getCode());
        entity.setModifiedName(UserUtil.getPartyCache() != null ? UserUtil.getPartyCache().getName() : "");
        customerCache.flushAllCacheByGroupCode(UserUtil.getBranchCode());
        return super.save(entity);
    }

    /**
     * 获取客户信息
     *
     * @param code 客户code
     * @return
     */
    @Override
    public OmsCustomerVO getOneInfo(String code) {
        OmsCustomer customer = getOne(new LambdaQueryWrapper<OmsCustomer>().eq(OmsCustomer::getCode, code).last("limit 1"));

        if (customer == null) {
            throw new NullPointerException();
        }
        OmsCustomerVO entity = new OmsCustomerVO();
        BeanUtil.copyProperties(customer, entity);
        List<String> areaList = new ArrayList<>();
        areaList.add(entity.getCountry());
        areaList.add(entity.getProvince());
        areaList.add(entity.getCity());
        areaList.add(entity.getCounty());
        String areaStr = "";
        if (StrUtil.isNotBlank(entity.getCountry())) {
            areaStr = areaCache.translateCountry(entity.getCountry());
        }

        if (StrUtil.isNotBlank(entity.getProvince())) {
            if (StrUtil.isNotBlank(areaStr)) {
                areaStr = areaStr + "/" + areaCache.translateProvince(entity.getProvince());
            } else {
                areaStr = areaCache.translateProvince(entity.getProvince());
            }
        }
        if (StrUtil.isNotBlank(entity.getCity())) {
            if (StrUtil.isNotBlank(areaStr)) {
                areaStr = areaStr + "/" + areaCache.translateCity(entity.getCity());
            } else {
                areaStr = areaCache.translateCity(entity.getCity());
            }
        }
        if (StrUtil.isNotBlank(entity.getCounty())) {
            if (StrUtil.isNotBlank(areaStr)) {
                areaStr = areaStr + "/" + areaCache.translateCounty(entity.getCounty());
            } else {
                areaStr = areaCache.translateCounty(entity.getCounty());
            }
        }


        entity.setArea(areaStr);
        entity.setAreaList(areaList);
        return entity;
    }

    /**
     * 更新客户信息
     *
     * @param entity
     * @return
     */
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public int updateByCode(OmsCustomerDTO entity) {
        OmsCustomer customerDb = baseMapper.selectOne(new QueryWrapper<OmsCustomer>().lambda().eq(OmsCustomer::getCode, entity.getCode()));
        Optional.ofNullable(customerDb).orElseThrow(() -> new ServiceException("查不到供应商信息"));
        OmsCustomer customer = new OmsCustomer();
        BeanUtil.copyProperties(entity, customer);
        customer.setCustomerCode(customerDb.getCustomerCode());
        List<String> areaList = entity.getAreaList();
        if (IterUtil.isNotEmpty(areaList) && areaList.size() == NumConst.NUM_FOUR) {
            customer.setCountry(areaList.get(NumConst.NUM_ZERO));
            customer.setProvince(areaList.get(NumConst.NUM_ONE));
            customer.setCity(areaList.get(NumConst.NUM_TWO));
            customer.setCounty(areaList.get(NumConst.NUM_THREE));
        }

        customer.setModifiedBy(UserUtil.getCode());
        customer.setModifiedName(UserUtil.getPartyCache() != null ? UserUtil.getPartyCache().getName() : "");
        return updateByCode(customer);
    }


}
